package com.mall.module.product.converter;

import com.mall.module.product.domain.dto.*;
import org.mapstruct.Mapper;
import org.springframework.util.CollectionUtils;

import javax.validation.ValidationException;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 商品数据转换器
 * <p>
 * 企业级规范实现：
 * 1. 使用 MapStruct 实现高性能对象转换
 * 2. 内置安全过滤机制（XSS防护）
 * 3. 支持自定义业务规则校验
 * 4. 空值安全处理
 * 5. 类型安全转换
 */
@Mapper(componentModel = "spring")
public abstract class ProductConverter {

    // XSS过滤规则
    private static final Pattern[] XSS_PATTERNS = {
        Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
        Pattern.compile("src[\r\n]*=[\r\n]*\\'(.*?)\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
        Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE)
    };

    // 主转换方法：将请求对象转换为DTO
    public ProductCreateDTO toCreateDto(ProductCreateDTO request) {
        if (request == null) {
            return null;
        }

        return ProductCreateDTO.builder()
            .spuInfo(toSpuDto(request.getSpuInfo()))
            .skuList(toSkuDtos(request.getSkuList()))
            .attributes(toAttributeDtos(request.getAttributes()))
            .marketingInfo(toMarketingDto(request.getMarketingInfo()))
            .build();
    }

    // SPU 转换
    public ProductSpuDTO toSpuDto(ProductSpuDTO request) {
        if (request == null) {
            return null;
        }
        
        ProductSpuDTO result = new ProductSpuDTO();
        
        // 复制基本属性
        result.setId(request.getId());
        result.setName(filterXss(request.getName()));
        result.setCategoryId(request.getCategoryId());
        result.setBrandId(request.getBrandId());
        result.setShippingTemplateId(request.getShippingTemplateId());
        result.setMainImage(request.getMainImage());
        result.setAlbumImages(request.getAlbumImages());
        result.setVideo(request.getVideo());
        result.setDescription(filterXss(request.getDescription()));
        result.setDetail(filterXss(request.getDetail()));
        result.setStatus(request.getStatus());
        
        return result;
    }

    // SKU 列表转换
    public List<ProductSkuDTO> toSkuDtos(List<ProductSkuDTO> requests) {
        if (CollectionUtils.isEmpty(requests)) {
            return Collections.emptyList();
        }

        // 并行处理提升性能（大数据量场景）
        return requests.parallelStream()
            .map(this::toSkuDto)
            .collect(Collectors.toList());
    }

    // SKU 单个转换
    public ProductSkuDTO toSkuDto(ProductSkuDTO request) {
        if (request == null) {
            return null;
        }
        
        ProductSkuDTO result = new ProductSkuDTO();
        
        // 复制基本属性
        result.setSkuCode(request.getSkuCode());
        result.setName(filterXss(request.getName()));
        result.setImages(request.getImages());
        result.setPrice(request.getPrice());
        result.setMarketPrice(request.getMarketPrice());
        result.setCostPrice(request.getCostPrice());
        result.setStock(request.getStock());
        result.setStockWarning(request.getStockWarning());
        result.setWeight(request.getWeight());
        result.setVolume(request.getVolume());
        result.setLimitPerOrder(request.getLimitPerOrder());
        
        // 处理规格数据，应用XSS过滤
        if (request.getSpecData() != null) {
            result.setSpecData(filterSpecData(request.getSpecData()));
        }
        
        // 处理预售配置
        result.setPresellConfig(request.getPresellConfig());
        
        return result;
    }

    // 属性转换
    public List<ProductAttributeDTO> toAttributeDtos(List<ProductAttributeDTO> requests) {
        if (CollectionUtils.isEmpty(requests)) {
            return Collections.emptyList();
        }
        return requests.stream()
            .map(this::toAttributeDto)
            .collect(Collectors.toList());
    }

    // 属性单个转换
    public ProductAttributeDTO toAttributeDto(ProductAttributeDTO request) {
        if (request == null) {
            return null;
        }
        
        ProductAttributeDTO result = new ProductAttributeDTO();
        result.setAttributeId(request.getAttributeId());
        result.setAttributeValue(filterAttributeValue(request.getAttributeValue()));
        
        return result;
    }

    // 营销信息转换
    public ProductMarketingDTO toMarketingDto(ProductMarketingDTO request) {
        if (request == null) {
            return null;
        }

        return ProductMarketingDTO.builder()
            .tagIds(request.getTagIds())
            .promotionIds(request.getPromotionIds())
            .isNew(request.getIsNew())
            .isRecommend(request.getIsRecommend())
            .services(request.getServices())
            .build();
    }

    // 自定义转换方法：价格转换（防止精度丢失）
    public BigDecimal toPrice(Double value) {
        if (value == null) {
            return null;
        }
        // 使用字符串转换避免浮点数精度问题
        return new BigDecimal(value.toString());
    }

    // 自定义转换方法：XSS过滤
    public String filterXss(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        
        // 使用正则表达式过滤高危脚本
        String sanitized = input;
        for (Pattern pattern : XSS_PATTERNS) {
            sanitized = pattern.matcher(sanitized).replaceAll("");
        }
        
        // 移除特殊控制字符
        sanitized = sanitized.replaceAll("[\u0000-\u001F]", "");
        
        return sanitized;
    }

    // 自定义转换方法：规格数据XSS过滤
    @SuppressWarnings("unchecked")
    public Map<String, String> filterSpecData(Map<String, String> specData) {
        if (specData == null) {
            return null;
        }
        
        return specData.entrySet().stream()
            .collect(Collectors.toMap(
                entry -> filterXss(entry.getKey()),
                entry -> filterXss(entry.getValue())
            ));
    }

    // 自定义转换方法：属性值XSS过滤
    public String filterAttributeValue(String input) {
        return filterXss(input);
    }

    // 业务规则校验：SKU编码唯一性
    protected void validateSkuCodes(List<ProductSkuDTO> skuList) {
        if (CollectionUtils.isEmpty(skuList)) {
            return;
        }

        Set<String> skuCodes = skuList.stream()
            .map(ProductSkuDTO::getSkuCode)
            .collect(Collectors.toSet());

        if (skuCodes.size() != skuList.size()) {
            throw new ValidationException("SKU编码必须唯一");
        }
    }
}